﻿Imports System.Windows.Media
Imports System.Windows
Imports System.Xml
Imports System.Collections.ObjectModel
Imports System.Threading.Tasks
Imports System.Windows.Threading
Imports FuncClasses
Imports HtmlAgilityPack
Imports System.Windows.Controls
Imports System.Windows.Media.Imaging

Public Class DHLTab
    Private calendar As New Windows.Controls.Calendar
    Private state As CalendarState = CalendarState.Uninitialized
    Private _parent As Biller.Window1
    Private _parent2 As AuftragsTab
    Private datestart As Date
    Private dateend As Date
    Private xml As New XmlDocument
    Private helper As IDatabase
    Private WithEvents timer1 As New DispatcherTimer
    'Private WithEvents timer2 As New DispatcherTimer
    Private connectedlist As New Collection(Of FuncClasses.KeyValuePairs)
    Private tbl As DataTable

    Public Sub New(ByRef parent As Biller.Window1, ByRef AuftragsTab As AuftragsTab)

        ' Dieser Aufruf ist für den Designer erforderlich.
        InitializeComponent()

        ' Fügen Sie Initialisierungen nach dem InitializeComponent()-Aufruf hinzu.
        AddHandler calendar.SelectedDatesChanged, AddressOf Calendar1_SelectedDatesChanged
        _parent = parent
        helper = parent.Database
        _parent2 = AuftragsTab

        'Get Start and End of the week
        Dim datum As Date = Date.Today
        Do Until datum.DayOfWeek = DayOfWeek.Monday
            datum = datum.AddDays(-1)
        Loop
        datestart = datum
        buttonDateStart.Header = "Vom " + FuncClasses.Datum.DateToString(datum)

        datum = Date.Today
        Do Until datum.DayOfWeek = DayOfWeek.Sunday : datum = datum.AddDays(1) : Loop
        dateend = datum
        buttonDateEnd.Header = "Bis zum " + FuncClasses.Datum.DateToString(datum)
        RefreshTimeSpan()
    End Sub

    Private Sub buttonDateStart_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles buttonDateStart.Click
        If state = CalendarState.Start Then
            _parent.MainGrid.Children.Remove(calendar)
            state = CalendarState.Uninitialized
        Else
            state = CalendarState.Start
            If _parent.MainGrid.Children.Contains(calendar) Then
                _parent.MainGrid.Children.Remove(calendar)
            End If
            calendar.Visibility = Windows.Visibility.Visible
            _parent.MainGrid.Children.Add(calendar)
            ' Return the offset vector for the TextBlock object.
            Dim vector As Windows.Vector = VisualTreeHelper.GetOffset(buttonDateStart)

            ' Convert the vector to a point value.
            Dim p As New Windows.Point(vector.X, vector.Y)
            p.X += buttonDateStart.ActualWidth / 2
            calendar.Margin = New Thickness(p.X, 0, 0, 0)
            calendar.HorizontalAlignment = Windows.HorizontalAlignment.Left
        End If

    End Sub

    Private Sub buttonDateEnd_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles buttonDateEnd.Click
        If state = CalendarState.Ende Then
            _parent.MainGrid.Children.Remove(calendar)
            state = CalendarState.Uninitialized
        Else
            state = CalendarState.Ende
            If _parent.MainGrid.Children.Contains(calendar) Then
                _parent.MainGrid.Children.Remove(calendar)
            End If
            calendar.Visibility = Windows.Visibility.Visible
            _parent.MainGrid.Children.Add(calendar)
            ' Return the offset vector for the TextBlock object.
            Dim vector As Windows.Vector = VisualTreeHelper.GetOffset(buttonDateEnd)

            ' Convert the vector to a point value.
            Dim p As New Windows.Point(vector.X, vector.Y)
            p.X += buttonDateEnd.ActualWidth / 2
            calendar.Margin = New Thickness(p.X, 0, 0, 0)
            calendar.HorizontalAlignment = Windows.HorizontalAlignment.Left
        End If
    End Sub

    Private Sub Calendar1_SelectedDatesChanged(ByVal sender As System.Object, ByVal e As System.Windows.Controls.SelectionChangedEventArgs)
        Dim datum As Date = calendar.SelectedDate.Value
        If state = CalendarState.Start Then
            datestart = datum
            buttonDateStart.Header = "Vom " + FuncClasses.Datum.DateToString(datum)
        Else
            dateend = datum
            buttonDateEnd.Header = "Bis zum " + FuncClasses.Datum.DateToString(datum)
        End If
        state = CalendarState.Uninitialized
        _parent.MainGrid.Children.Remove(calendar)
        RefreshTimeSpan()
    End Sub

    Private Sub RefreshTimeSpan()
        InitializeFile(System.AppDomain.CurrentDomain.BaseDirectory() + "Firma\" + helper.LastCompany + "\tracking.xml")
        xml.Load(System.AppDomain.CurrentDomain.BaseDirectory() + "Firma\" + helper.LastCompany + "\tracking.xml")
        Dim root As XmlElement = xml.DocumentElement.SelectSingleNode("/trackinglist")
        Dim nodeList As XmlNodeList = root.GetElementsByTagName("package")
        Dim mutex As New System.Threading.Mutex

        Dim list As IEnumerator = nodeList.GetEnumerator
        Dim xmllist As New Collection(Of XmlElement)
        Dim xmllistintimespan As New Collection(Of XmlElement)
        Do While (list.MoveNext())
            xmllist.Add(list.Current)
        Loop

        Parallel.ForEach(xmllist, Sub(item As XmlElement)
                                      Dim datum As New FuncClasses.Datum(item.Attributes.GetNamedItem("date").Value.ToString)
                                      Dim actual As New Date(datum.Jahr, datum.Monat, datum.Tag)
                                      If (actual.Ticks >= datestart.Ticks AndAlso actual.Ticks <= dateend.Ticks) Then
                                          mutex.WaitOne()
                                          xmllistintimespan.Add(item)
                                          mutex.ReleaseMutex()
                                      End If
                                  End Sub)
        tbl = New DataTable
        tbl.Columns.Add("Date")
        tbl.Columns.Add("Number")
        tbl.Columns.Add("Packager")
        tbl.Columns.Add("LastState")
        tbl.PrimaryKey = {tbl.Columns(1), tbl.Columns(2)}
        connectedlist.Clear()

        For Each item As XmlElement In xmllistintimespan
            Dim versender As Packager = item.Attributes.GetNamedItem("packager").Value
            tbl.Rows.Add(item.Attributes.GetNamedItem("date").Value.ToString, item.Attributes.GetNamedItem("trackingnr").Value.ToString, versender.ToString, "Wird abgefragt ...")
            Dim temp As IPackager
            Select Case versender
                Case Packager.DHL
                    temp = New DHL(item.Attributes.GetNamedItem("trackingnr").Value.ToString)
                Case Packager.Hermes
                    temp = New Hermes(item.Attributes.GetNamedItem("trackingnr").Value.ToString)
            End Select

            connectedlist.Add(New KeyValuePairs(item.Attributes.GetNamedItem("trackingnr").Value.ToString, temp))
        Next
        ListView1.DataContext = tbl
        'ListView1.Items.Refresh()
        timer1.Interval = New TimeSpan(0, 0, 0, 1, 0)
        timer1.Start()

        ListView1.UpdateLayout()
    End Sub

    Private Sub Timer_Tick(sender As Object, e As EventArgs) Handles timer1.Tick
        ' ...
        '  ..
        '   .
        '    
        ' .  
        ' .. 
        ' ...
        Try
            Dim openquests As Boolean = False
            For Each kvp As KeyValuePairs In connectedlist
                If kvp.Key IsNot Nothing Then
                    Dim temp As IPackager = kvp.Value
                    If String.IsNullOrEmpty(temp.LastState) = False Then
                        Dim dr As DataRow = tbl.Rows.Find({temp.Package_ID, temp.Packager.ToString})
                        dr("LastState") = temp.LastState
                    End If
                End If
            Next

            For Each r As DataRow In tbl.Rows
                If r("LastState").ToString.Contains("Wird abgefragt") Then
                    openquests = True
                    If r("LastState").ToString.EndsWith(" ...") Then
                        r("LastState") = "Wird abgefragt  .."
                    ElseIf r("LastState").ToString.EndsWith("  ..") Then
                        r("LastState") = "Wird abgefragt   ."
                    ElseIf r("LastState").ToString.EndsWith("   .") Then
                        r("LastState") = "Wird abgefragt    "
                    ElseIf r("LastState").ToString.EndsWith("    ") Then
                        r("LastState") = "Wird abgefragt .  "
                    ElseIf r("LastState").ToString.EndsWith(" .  ") Then
                        r("LastState") = "Wird abgefragt .. "
                    ElseIf r("LastState").ToString.EndsWith(" .. ") Then
                        r("LastState") = "Wird abgefragt ..."
                    End If
                End If
            Next
            If openquests = False Then
                timer1.Stop()
            End If
        Catch ex As Exception

        End Try


        
    End Sub

    ''' <summary>
    ''' Methode to ensure that the XML file we want to read from really exists.
    ''' </summary>
    ''' <param name="path">Path to XML file we want to read.</param>
    ''' <remarks></remarks>
    Private Sub InitializeFile(path As String)
        Dim sb As New Text.StringBuilder
        sb.Append(path)
        'if the file doesn't exist, create a blank xml
        If Not IO.File.Exists(path) Then
            Dim fn As New IO.StreamWriter(IO.File.Open(path, IO.FileMode.Create))
            fn.WriteLine("<?xml version=""1.0"" encoding=""utf-8""?>")
            fn.WriteLine("<trackinglist>")
            fn.WriteLine("</trackinglist>")
            fn.Close() 'all done
        End If
    End Sub

    ''' <summary>
    ''' This methode is raised when the user selects an item from the listview
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub ListView1_SelectionChanged(sender As System.Object, e As System.Windows.Controls.SelectionChangedEventArgs) Handles ListView1.SelectionChanged
        If ListView1.SelectedItem IsNot Nothing Then
            ItemsPanel.Children.Clear()
            For Each drv As DataRowView In ListView1.SelectedItems
                For Each kvp As KeyValuePairs In connectedlist
                    If drv.Row("Number") = kvp.Key Then
                        Dim temp As IPackager = kvp.Value
                        ItemsPanel.Children.Add(temp.InfoControl)
                        Exit Sub
                    End If
                Next
            Next
        End If
    End Sub

    Private Sub UserControl_Loaded(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded
        ListView1.DataContext = tbl
        UpdateLayout()
        ListView1.UpdateLayout()
    End Sub

    Private Sub ListView1_Loaded(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles ListView1.Loaded
        ColumnDatum.Width = helperWidth1.ActualWidth
        ColumnNr.Width = helperWidth2.ActualWidth
        ColumnVersender.Width = helperWidth3.ActualWidth
        ColumnStatus.Width = helperWidth4.ActualWidth
    End Sub

    Private Sub ListView1_SizeChanged(sender As System.Object, e As System.Windows.SizeChangedEventArgs) Handles ListView1.SizeChanged
        ColumnDatum.Width = helperWidth1.ActualWidth
        ColumnNr.Width = helperWidth2.ActualWidth
        ColumnVersender.Width = helperWidth3.ActualWidth
        ColumnStatus.Width = helperWidth4.ActualWidth
    End Sub

    Private Sub buttonRefresh_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles buttonRefresh.Click
        RefreshTimeSpan()
    End Sub

End Class

Enum CalendarState
    Start = 0
    Ende = 1
    Uninitialized = 2
End Enum
